// DESCRIPTION: Verilator: Verilog example module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2017 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
//======================================================================

// Include common routines
#include <cstdlib>
#include <cstdio>
#include <ctime>
#include <verilated.h>

// Include model header, generated from Verilating "top.v"
#include "verilator_io_test.h"

int main(int argc, char **argv, char **env) {
  // See a similar example walkthrough in the verilator manpage.

  // This is intended to be a minimal example.  Before copying this to start a
  // real project, it is better to start with a more complete example,
  // e.g. examples/c_tracing.

  // Prevent unused variable warnings
  if (false && argc && argv && env) {}

  // Construct the Verilated model, from Vtop.h generated from Verilating "top.v"
  verilator_io_test *top = new verilator_io_test;

  srand(time(nullptr));

  uint32_t cnt = 0;

  auto exec = [&](int n) {
    top->clk = 0;
    top->eval();
    top->clk = 1;
    top->eval();
    cnt++;
    // sleep(1);
    //
  };

  top->resetn = 0;
  exec(5);
  top->resetn = 1;

  // Simulate until $finish
  int a = 0, b = 0;
  while (!Verilated::gotFinish()) {
    top->a = a = rand() % 2;
    top->b = b = rand() % 2;
    // Evaluate model
    exec(1);
    printf("[%03lu] ", cnt);
    if (top->c != (a ^ b)) {
      printf("Err: a = %d, b = %d, c = %d\n", a, b, top->c);
    } else {
      printf("OK.\n");
    }
  }

  // Final model cleanup
  top->final();

  // Destroy model
  delete top;

  // Return good completion status
  return 0;
}
